#ifndef __FACTORY_H__
#define __FACTORY_H__
#include "head.h"
#include "md5.h"
#include "work_que.h"
#include "database_op.h"

#define FILENAME "file"
#define USERSPACE "/home/ario/c-linux-learning/netdisk/user_space/"



// 线程池结构体
typedef struct {
    Que_t que; // 任务队列
    pthread_cond_t cond; // 线程池条件变量
    pthread_t *pthid; // 线程
    short flag; // 线程池启动标志
} Factory_t;

// 数据传送结构体
typedef struct 
{
    int data_len;
    char buf[1000];
} train_t;

// 数据传送结构体，带操作码
typedef struct 
{
    int data_len;
    int state; // 存放操作状态码
    char buf[100];
}train_state_t;

// 每个操作对应的操作码
enum command {
    REGISTER,
    LOGIN,
    LS,
    CD,
    PWD,
    REMOVE,
    GETS,
    PUTS,
    TOKEN,
};

// 每个客户端的状态维护结构体
typedef struct 
{
    int new_fd; // 客户端连接
    char path[100]; // cd、pwd
    int parent_code; // 当前所在文件夹的id
    int user_id; // 用户id
    char token[100]; // 登录成功，随机生成一个Token发送给客户端
}Client_State_t;


extern __thread Client_State_t cur_client;

/***********网盘***********/

// 与客户端进行交互
int do_reception(int new_fd);
int test_script(int new_fd);

// 用户注册
int exec_register(train_state_t t_s_data, int new_fd);

// 用户登录
int exec_login(train_state_t t_s_data, int new_fd);

// 登录后的其他命令
int exec_after_login(train_state_t t_s_data, int new_fd);

int exec_cd(train_state_t t_s_data);

int exec_ls(train_state_t t_s_data);

int exec_pwd(train_state_t t_s_data);

int exec_remove(train_state_t t_s_data);

int exec_gets(train_state_t t_s_data);

int exec_puts(train_state_t t_s_data);

/**********网盘工具函数***********/

// 生成盐值
int generateSalt(char *str);

// 生成md5值
int Compute_file_md5(const char *file_path, char *md5_str);


/***********线程池***********/

// 初始化线程池
void factory_init(Factory_t* pf, int thread_num, int capacity);

// 启动线程池
void factory_start(Factory_t *pf, int thread_num);

// 子线程流程
void* thread_handle(void *p);

// 初始化socket
int tcp_init(int* socket_fd,char* ip,char* port);

// socket、bind、listen
int tcp_init(int* socket_fd,char* ip,char* port);

// 将文件描述符添加到epfd的监视队列
int epoll_add(int epfd,int fd);

// 接收文件
int download_file(int remote_fd);

// 发送文件
int upload_file(int remote_fd, char *file_name);

// 循环接收
int recv_n(int sfd, void* buf, int data_len);

// 循环发送
int send_n(int sfd, void* buf, int data_len);
#endif